#pragma once

#include "socket.hpp"
#include "protocol.hpp"
#include "task.hpp"

const int MAXRECONNECT = 5;
class TcpClient
{
public:
    TcpClient(const std::string& server_ip, uint16_t server_port)
        :_sock_fd(-1)
        ,_server_sock(server_port, server_ip)
    {}


    void Init()
    {
        _sock_fd = socket(AF_INET, SOCK_STREAM, 0);
        if(_sock_fd < 0)
        {
            perror("socket create fail");
            exit(1);
        }
        if (_server_sock.Init() == false)
        {
            exit(1);
        }
    }

    ~TcpClient()
    {
        if(_sock_fd > 0)
        {
            close(_sock_fd);
        }
    }


    bool Connect()
    {
        int err = _server_sock.Connect(_sock_fd);
        if(err < 0)
        {
            return false;
        }
        return true;
    }


    // int Send(const std::string& msg)
    // {
    //     int WrietSize = _server_sock.Send(_sock_fd, msg);
    //     return WrietSize;
    // }   

    bool Send(const Request& req)
    {
        std::string msg = req.Serialize();
        if(msg == "")
        {
            return false;
        }
        int WrietSize = _server_sock.Send(_sock_fd, msg);
        if(WrietSize < 0)
        {
            return false;
        }
        return true;
    }


    // int Recv(std::string& msg)
    // {
    //     int ReadSize = _server_sock.Recv(_sock_fd, msg);
    //     return ReadSize;  
    // }


    bool Recv(Response& resp)
    {
        std::string msg;
        int ReadSize = _server_sock.Recv(_sock_fd, msg);
        if(ReadSize < 0)
        {
            return false;
        }
        if(ReadSize == 0)
        {
            return false;
        }
        if(resp.Deserialize(msg) == false)
        {
            return false;
        }
        return true;
    }

    int GetFd()
    {
        return _sock_fd;
    }
private:
    int _sock_fd;
    TcpSocket _server_sock;
};